/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package Controller;

/**
 *
 * @author asouza, subx
 */
public class AVLNode<T extends Comparable<T>, K> {
    private T key;
    private K ref;
    private AVLNode<T, K> left;
    private AVLNode<T, K> right;
    private Integer height;

    
    public AVLNode(){
        setHeight(0);
        setKey(null);
        setLeft(null);
        setRight(null);
    }

    public AVLNode(T k, K r, AVLNode<T, K> left, AVLNode<T, K> right){
        setKey(k);
        setRef(r);
        setHeight(1);
        setLeft(left);
        setRight(right);
    }

    public boolean isTerminal () {
        return (this.getKey() == null);
    }

    public boolean isLeaf(){
        return (getLeft().isTerminal() && getRight().isTerminal());
    }

    public int getBalanceFactor(){
        return getLeft().getHeight() - getRight().getHeight();
    }

    public void adjustHeight(){
        if(isLeaf())
            setHeight(1);
        else if(getLeft() != null && getRight() != null){
            if(getLeft().getHeight() > getRight().getHeight())
                setHeight(getLeft().getHeight() + 1);
            else
                setHeight(getRight().getHeight() + 1);
        }else{
            if(getLeft() != null && getRight() == null)
                setHeight(getLeft().getHeight() + 1);
            else if(getRight() != null && getLeft() == null)
                setHeight(getRight().getHeight() + 1);
        }
    }

    public T getKey() {
        return key;
    }

    public void setKey(T key) {
        this.key = key;
    }

    public AVLNode<T, K> getLeft() {
        return left;
    }

    public void setLeft(AVLNode<T, K> left) {
        this.left = left;
    }

    public AVLNode<T, K> getRight() {
        return right;
    }

    public void setRight(AVLNode<T, K> right) {
        this.right = right;
    }

    public Integer getHeight() {
        return height;
    }

    public void setHeight(Integer height) {
        this.height = height;
    }

    public K getRef() {
        return ref;
    }

    public void setRef(K ref) {
        this.ref = ref;
    }
}
